<?php


namespace App\Http\Controller;
use App\Model\Entity\LogIn;
use App\Model\Entity\Token;
use App\Model\Entity\User;
use App\Http\Utils\Jwt;
use ReflectionException;
use Swoft\Bean\Exception\ContainerException;
use Swoft\Db\Exception\DbException;
use Swoft\Exception\SwoftException;
use Swoft\Http\Message\Response;
use Swoft\Http\Server\Annotation\Mapping\Controller;
use Swoft\Http\Server\Annotation\Mapping\Middleware;
use Swoft\Http\Server\Annotation\Mapping\RequestMapping;
use App\Http\Middleware\AuthMiddleware;
use Swoft\Log\Helper\Log;
use App\Http\Utils\InputFilter;

/**
 * Class UserController
 * @Controller("/v1/User")
 * @package App\Http\Controller
 */
class UserController
{
    /**
     * 写日志
     * @param $data
     * @throws DbException
     */
    private function log_w($data)
    {
        $Log = LogIn::new();
        $Log->setDate(date("Y-m-d H:i:s"));
        $Log->setLog((string)$data);
        try {
            $Log->save();
        } catch (ReflectionException $e) {
            Log::error($e->getMessage());
        } catch (ContainerException $e) {
            Log::error($e->getMessage());
        } catch (DbException $e) {
            Log::error($e->getMessage());
        }
    }
    /**
     * @RequestMapping("/v1/login")
     * @return Response
     * @throws SwoftException
     * @throws \Swoft\Db\Exception\DbException
     */
    public function index(): Response
    {
        $request = Context()->getRequest();
        $response = Context()->getResponse();

        $mentod = $request->getMethod();


        if ($mentod == "POST")
            $data = $request->post();
        else {
            return $response->withStatus(404);

        }
//        if(is_array($data))
//            $this->log_w(json_encode($data) . json_encode($request->getHeader("Content-Type")));
//        else
//            $this->log_w(($data).json_encode($request->getHeader("Content-Type")));
        if(!isset($data["user"]) || !isset($data["pwd"]))
        {
            return $response->withStatus(400)->withData(["error"=>"1","errorMsg"=>"没有设置用户名密码"]);
        }
        if(!preg_match('/^[\w]{4,20}$/u',$data["user"]))
        {
            return $response->withStatus(400)->withData(["error"=>"2","errorMsg"=>"用户名错误：用户名是英文、数字4-20位字符"]);
        }
        if(!preg_match('/^[\w]{8,32}$/u',$data["pwd"]))
        {
            return $response->withStatus(400)->withData(["error"=>"3","errorMsg"=>"密码非法"]);
        }
        if(User::where("UserName",$data["user"])->where("pwd",$data["pwd"])->get()->count() <= 0)
        {
            return $response->withStatus(400)->withData(["error"=>"4","errorMsg"=>"用户名错误或密码错误"]);
        }
        $rec = array("user"=>$data["user"],"Token"=> Jwt::getToken($data["user"]));
        if($rec["Token"] == false)
            return $response->withStatus(500)->withData(["error"=>"6","errorMsg"=>"数据库错误"]);

        return $response->withData($rec);

    }
    /**
     * @RequestMapping("/v1/logout")
     * @Middleware(AuthMiddleware::class)
     * @return Response
     * @throws SwoftException
     */
    public function logout(): Response
    {
        $request = Context()->getRequest();
        $response = Context()->getResponse();

        $user = Context()->get("user");
        if($user == "")
            return $response->withStatus(500)->withData(["errorMsg"=>"服务器错误"]);
        try {
            Token::where("UserName", $user)->delete();
        } catch (\ReflectionException $e) {
            return $response->withStatus(500)->withData(["errorMsg"=>"服务器错误ReflectionException:".$e->getMessage()]);
        } catch (ContainerException $e) {
            return $response->withStatus(500)->withData(["errorMsg"=>"服务器错误ContainerException:".$e->getMessage()]);
        } catch (DbException $e) {
            return $response->withStatus(500)->withData(["errorMsg"=>"服务器错误DbException:".$e->getMessage()]);
        }

        $rec = array("user" => $user,"logout_date"=>time());

        return $response->withData($rec);
    }

    /**
     * @RequestMapping("/v1/register")
     * @return Response
     * @throws SwoftException
     */
    public function register(): Response
    {
        $request = Context()->getRequest();
        $response = Context()->getResponse();

        $mentod = $request->getMethod();


        if ($mentod == "POST")
            $data = $request->post();
        else {
            return $response->withStatus(404);

        }
        if(!isset($data["user"]) || !isset($data["pwd"]))
        {
            return $response->withStatus(404)->withData(["error"=>"1","errorMsg"=>"没有设置用户名密码"]);
        }
        if(!preg_match('/^[\w]{4,20}$/u',$data["user"]))
        {
            return $response->withStatus(404)->withData(["error"=>"2","errorMsg"=>"用户名错误：用户名是英文、数字4-20位字符"]);
        }
        if(!preg_match('/^[\w]{8,32}$/u',$data["pwd"]))
        {
            return $response->withStatus(404)->withData(["error"=>"3","errorMsg"=>"密码非法"]);
        }
        $inertData = array("UserName"=>$data["user"] ,"pwd"=>$data["pwd"]);

        if(isset($data["email"]))
        {
            if(!preg_match('/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/',$data["email"]))
            {
                return $response->withStatus(404)->withData(["error"=>"4","errorMsg"=>"邮箱格式错误"]);
            }
            $inertData["email"] = $data["email"];
        }
        if(isset($data["signature"]))
            $inertData["signature"] = $data["signature"];
        try
        {

            if(User::where("UserName",$data["user"])->get()->count() <= 0)
                User::insert($inertData);
            else
                return $response->withStatus(404)->withData(["error"=>"5","errorMsg"=>"用户名已存在"]);

            return $response->withData(["user"=>$data["user"],"userid"=>User::where("UserName",$data["user"])->get()[0]["userid"],"time"=>time()]);
        }
        catch (\ReflectionException $e) {
            return $response->withStatus(500)->withData(["errorMsg"=>"服务器错误ReflectionException:".$e->getMessage()]);
        } catch (ContainerException $e) {
            return $response->withStatus(500)->withData(["errorMsg"=>"服务器错误ContainerException:".$e->getMessage()]);
        } catch (DbException $e) {
            return $response->withStatus(500)->withData(["errorMsg"=>"服务器错误DbException:".$e->getMessage()]);
        }

    }
}
